package com.project.common.tag;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.project.service.tags.WidgetService;


/**
 * @author kale
 * Accessing database to generate select input widget according to the id which passed in this widget.
 */
@Component
public class SelectTag extends TagSupport {

	private static final long serialVersionUID = -7762361372178555026L;

	private static Logger logger = LoggerFactory.getLogger(SelectTag.class);
	
	private String cssClass; 
	
	private String type = null;
	private String id = null;
	private String name = null;
	private String onclick = null;
	private String onchange = null;
	private String onfocus = null;
	private boolean disabled = false;
	private boolean readonly = false;
	private String style = null;
	private String styleClass = null;
	private String size = null;
	private String value = null;
	private boolean blank = false;
	private boolean showValue = true;
	private String optionDisableValue = null;
	private String optionNoShowValue = null;
	private String onblur;
	private String title;
	
	private List<Map<String, String>> list;

	private WidgetService widgetService;

	public int doEndTag() throws JspException{
	
   WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(pageContext.getServletContext());   
   widgetService = (WidgetService)ctx.getBean("defaultWidgetService");   
		list = this.getList();
	    JspWriter out = pageContext.getOut();
	   	try{
	   		StringBuffer results = null;
	   		if(StringUtils.isBlank(this.styleClass)){
	   			results = new StringBuffer("<select class=\"form-control\"");
	   		}else{
	   			results = new StringBuffer("<select ");
	   		}
			results = getAllProp(results);
			results.append(">");
			if (this.blank) {
				if (this.value == null)
					results.append("<option value=\"\" selected=\"selected\">请选择</option>");
				else {
					results.append("<option value=\"\">请选择</option>");
				}
			}
	   		
	   		for(int i=0;i<list.size();i++){
	   			Map<String, String> map = (Map<String, String>) list.get(i);
	   			if(map.keySet().iterator().hasNext()){
	   				String key = map.keySet().iterator().next();
		   			
	   				//List<String> list = Arrays.asList(this.optionNoShowValue.split(","));
		   			if(StringUtils.isNotBlank(this.optionNoShowValue) && Arrays.asList(this.optionNoShowValue.split(",")).contains(map.get(key))){
		   				continue;
		   			}else{
		   				results.append("<option value=\"");
		   				results.append(map.get(key));
		   				results.append("\"");
		   				if (map.get(key).equals(this.value)) {
		   					results.append(" selected=\"selected\"");
		   				}
		   				if(StringUtils.isNotBlank(this.optionDisableValue)){
		   					List<String> a = Arrays.asList(this.optionDisableValue.split(","));
		   					if (a.contains(map.get(key))) {
		   						results.append(" disabled=\"disabled\"");
		   					}
		   				}
		   				results.append(">");
		   				if (this.showValue) {
		   					results.append(map.get(key));
		   					results.append(" - ");
		   				}
		   				results.append(formatStr(key));
		   				results.append("</option>");
		   			}
	   			}
	   		}
	   		
	   		results.append("</select>");
	   		out.print(results.toString());
	   	} catch(Exception e){
	   		logger.error("create select widget failed", e);
	   		e.printStackTrace();
	   	}
	   	return SKIP_BODY;
	}
	
	private StringBuffer getAllProp(StringBuffer results) throws JspException {
		prepareAttribute(results, "onclick", getOnclick());
		prepareAttribute(results, "onchange", getOnchange());
		prepareAttribute(results, "onfocus", getOnfocus());

		if (getDisabled()) {
			results.append(" disabled=\"disabled\"");
		}
		if (getReadonly()) {
			results.append(" readonly=\"readonly\"");
		}
		prepareAttribute(results, "style", getStyle());
		prepareAttribute(results, "class", getStyleClass());
		prepareAttribute(results, "name", getName());
		prepareAttribute(results, "id", getId());
		prepareAttribute(results, "size", getSize());
		prepareAttribute(results, "value", getValue());

		return results;
	}
	
	protected void prepareAttribute(StringBuffer handlers, String name,
			Object value) {
		if (value != null) {
			handlers.append(" ");
			handlers.append(name);
			handlers.append("=\"");
			handlers.append(value);
			handlers.append("\"");
		}
	}
	
	private String formatStr(String s) {
		if (s != null) {
			return s.trim();
		}
		return "";
	}

	/**
	 * @return the cssClass
	 */
	public String getCssClass() {
		return cssClass;
	}

	/**
	 * @param cssClass the cssClass to set
	 */
	public void setCssClass(String cssClass) {
		this.cssClass = cssClass;
	}

	/**
	 * @return the id
	 */
	public String getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the onblur
	 */
	public String getOnblur() {
		return onblur;
	}

	/**
	 * @param onblur the onblur to set
	 */
	public void setOnblur(String onblur) {
		this.onblur = onblur;
	}

	/**
	 * @return the onclick
	 */
	public String getOnclick() {
		return onclick;
	}

	/**
	 * @param onclick the onclick to set
	 */
	public void setOnclick(String onclick) {
		this.onclick = onclick;
	}

	/**
	 * @return the onchange
	 */
	public String getOnchange() {
		return onchange;
	}

	/**
	 * @param onchange the onchange to set
	 */
	public void setOnchange(String onchange) {
		this.onchange = onchange;
	}

	/**
	 * @return the style
	 */
	public String getStyle() {
		return style;
	}

	/**
	 * @param style the style to set
	 */
	public void setStyle(String style) {
		this.style = style;
	}

	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * @param title the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getOnfocus() {
		return onfocus;
	}

	public void setOnfocus(String onfocus) {
		this.onfocus = onfocus;
	}

	public boolean getDisabled() {
		return disabled;
	}

	public void setDisabled(boolean disabled) {
		this.disabled = disabled;
	}

	public boolean getReadonly() {
		return readonly;
	}

	public void setReadonly(boolean readonly) {
		this.readonly = readonly;
	}

	public String getStyleClass() {
		return styleClass;
	}

	public void setStyleClass(String styleClass) {
		this.styleClass = styleClass;
	}

	public String getSize() {
		return size;
	}

	public void setSize(String size) {
		this.size = size;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public boolean isBlank() {
		return blank;
	}

	public void setBlank(boolean blank) {
		this.blank = blank;
	}

	public boolean isShowValue() {
		return showValue;
	}

	public void setShowValue(boolean showValue) {
		this.showValue = showValue;
	}

	public String getOptionDisableValue() {
		return optionDisableValue;
	}

	public void setOptionDisableValue(String optionDisableValue) {
		this.optionDisableValue = optionDisableValue;
	}

	public String getOptionNoShowValue() {
		return optionNoShowValue;
	}

	public void setOptionNoShowValue(String optionNoShowValue) {
		this.optionNoShowValue = optionNoShowValue;
	}

	/**
	 * @return the list
	 */
	public List<Map<String, String>> getList() {
		ServletContext content=pageContext.getSession().getServletContext();
		List<Map<String, String>>  dicMap=(List<Map<String, String>>) content.getAttribute(type);
		if(dicMap==null){
			 List<Map<String, String>> newDicMap=widgetService.getSelectOptions(type);
			 content.setAttribute(type, newDicMap);
		}
		dicMap=(List<Map<String, String>>) content.getAttribute(type);
		return dicMap;
	}
}
